package com.nxy.cpfsfe.busi.bbatproc.chka;

import com.adtec.starring.exception.BaseException;
import com.adtec.starring.util.SpringUtil;
import com.nxy.cpfsfe.NCSChkaFilenameFilter;
import com.nxy.cpfsfe.cache.DbToParmToCache;
import com.nxy.cpfsfe.enumtype.NCSChkAFileTypEnum;
import com.nxy.cpfsfe.enumtype.RespCd;
import com.nxy.cpfsfe.mybatis.mapper.TdChkaSumMapper;
import com.nxy.cpfsfe.mybatis.pojo.TdChkaSum;
import com.nxy.cpfsfe.mybatis.pojo.TePChlSett;
import com.nxy.cpfsfe.mybatis.pojo.ToParm;
import com.nxy.cpfsfe.util.DateUtil;
import com.nxy.cpfsfe.util.FileUtil;
import com.nxy.cpfsfe.util.sftp.SFTPTransfer;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

/**
 * 
 * NCS侧对账类
 * 
 * @author jjw
 *
 */
public class NCSChkASrv extends AbsChkASrv {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(NCSChkASrv.class);

	private NCSChkAComponent ncsChkAComponent;
	
	public NCSChkASrv(){}
	
	public NCSChkASrv(String orgId,String pCId,Date chkAD,String mfeTyp){
		this.orgId = orgId;
		this.pCId = pCId;
		this.chkAD = chkAD;
		this.mfeTyp = mfeTyp;
		this.sqlSession = (SqlSession) SpringUtil.getBean("mybatisSqlSession");
		this.tePChlSett = new TePChlSett();
		this.tePChlSett.setOrgId(orgId);
		this.tePChlSett.setpCId(pCId);
		this.tePChlSett.setChkAD(chkAD);
		this.ncsChkAComponent = new NCSChkAComponent(orgId,pCId,DateUtil.date4Str(chkAD));
	}

	/**
	 * 
	 * Description:NCS下载对账文件
	 *
	 * @author jjw
	 * @data 2019年9月6日
	 */
	@Override
	protected void dlChkAF() {
		
		if(DbToParmToCache.getToParm().get("bizsys_bno_mapper/NGPS").getDataVal().equals(orgId)){
			//老e支付
			doDlChkAF("mfe2A_infos");
		}else if(DbToParmToCache.getToParm().get("bizsys_bno_mapper/NVAS").getDataVal().equals(orgId)){
			//老e管家
			doDlChkAF("mfe2B_infos");
		}else{
			//新行号从新版MFE下载
			if("A".equals(mfeTyp)){
				doDlChkAF("mfe3A_infos");
			}else if("B".equals(mfeTyp)){
				doDlChkAF("mfe3B_infos");
			}else{
				String errMsg = String.format("机构[%s]与[%s]通道[%s]日对账失败，无对应mfe类型[%s]", orgId,pCId,DateUtil.date3Str(chkAD),mfeTyp);
				throw new BaseException(RespCd.NCPO6037,errMsg);
			}
		}
		
	}
	
	/**
	 * 
	 * Description:NCS对账文件入库
	 *
	 * @author jjw
	 * @throws Exception 
	 * @data 2019年9月7日
	 */
	@Override
	protected void chkAFStrgDb(){
		
		Map<String,ToParm> config = DbToParmToCache.getToParm();
		
		String rootPath = config.get("ncs_chka/localPath").getDataVal() + File.separator + this.orgId;
		File rootDir = new File(rootPath);
		
		//过滤获得指定对账文件
		File[] chkAFs = rootDir.listFiles(new NCSChkaFilenameFilter());
		Map<String,File> chkAFMap = new HashMap<String,File>();
		for(File chkAF : chkAFs){
			chkAFMap.put(chkAF.getName().substring(0,4), chkAF);
		}
		
		try{
			//汇总对账文件入库
			File csumFile = chkAFMap.get(NCSChkAFileTypEnum.SUM_CHKA.getCode());
			int csumCount = regCsum(csumFile);
			LOGGER.info("汇总对账文件[{}]，文件大小[{}]B，总计录入[{}]条信息",csumFile.getAbsolutePath(),csumFile.length(),csumCount);
			
			//汇兑业务明细对账文件入库
			File cdttFile = chkAFMap.get(NCSChkAFileTypEnum.RM_BIZ.getCode());
			int cdttCount = regCdtt(cdttFile);
			LOGGER.info("汇兑业务明细对账文件[{}]，文件大小[{}]B，总计录入[{}]条信息",cdttFile.getAbsolutePath(),cdttFile.length(),cdttCount);
			
			//实时借贷业务明细对账文件入库
			File rtcdFile = chkAFMap.get(NCSChkAFileTypEnum.NOW_DRCR_BIZ.getCode());
			int rtcdCount = regRtcd(rtcdFile);
			LOGGER.info("实时借贷业务明细对账文件[{}]，文件大小[{}]B，总计录入[{}]条信息",rtcdFile.getAbsolutePath(),rtcdFile.length(),rtcdCount);
			
			updateChkASchedule("1",null,null,null);
		}catch(BaseException e){
			throw e;
		}catch(Exception e){
			String errMsg = String.format("机构[%s]与[%s]通道[%s]日对账失败，对账文件入库失败", orgId,pCId,DateUtil.date3Str(chkAD));
			throw new BaseException(RespCd.NCPO6037,e,errMsg);
		}
		
		
	}
	
	/**
	 * 
	 * Description:更新账务流水表
	 *
	 * @author jjw
	 * @data 2019年9月7日
	 */
	@Override
	protected void updateTbaSta() {

		ncsChkAComponent.updateTbaSta(pCId, orgId, DateUtil.getDate(), DateUtil.date4Str(chkAD));

		updateChkASchedule("2",null,null,null);
		
	}
	
	/**
	 * 
	 * Description:更新支付流水表
	 *
	 * @author jjw
	 * @data 2019年9月9日
	 */
	@Override
	protected void updatePSta() {

		ncsChkAComponent.updatePSta(pCId, orgId, DateUtil.getDate(), DateUtil.date4Str(chkAD));
		
		//删除对账文件
		delTmpF();
		
		updateChkASchedule("3","1",new Date(),"无");
		
	}
	
	/**
	 * 
	 * Description:删除临时对账文件
	 *
	 * @author jjw
	 * @data 2019年9月24日
	 */
	protected void delTmpF(){
		
		Map<String,ToParm> config = DbToParmToCache.getToParm();
		String localPath = config.get("ncs_chka/localPath").getDataVal();
		FileUtil.delFile(new File(localPath + File.separator + orgId));
		FileUtil.delFile(new File(localPath + File.separator + DateUtil.date4Str(this.chkAD) + this.orgId + ".tar"));
		
	}
	
	/**
	 * 
	 * Description:下载对账文件
	 *
	 * @author jjw
	 * @data 2019年9月29日
	 */
	private void doDlChkAF(String configCd){
		
		String host;
		Integer port;
		String username;
		String privateKey;
		Integer timeout;
		String localPath;
		String remotePath;
		String[] fileArray = new String[]{DateUtil.date4Str(this.chkAD) + this.orgId + ".tar"};
		
		try {
			Map<String,ToParm> config = DbToParmToCache.getToParm();
			String mfeConfig = config.get("ncs_chka/" + configCd).getDataVal();
			String[] mfeParams = mfeConfig.split(",");
			
			host = mfeParams[0];
			port = Integer.parseInt(mfeParams[1]);
			username = mfeParams[2];
			privateKey = System.getProperty("user.home") + File.separator + mfeParams[3];
			timeout = Integer.parseInt(mfeParams[4]);
			remotePath = mfeParams[5] + this.orgId + mfeParams[6];
			
			localPath = config.get("ncs_chka/localPath").getDataVal();
			
			LOGGER.info("下载对账文件[{}]，MFE配置信息：\nIP=[{}]\n端口=[{}]\n用户=[{}]\n超时时间=[{}]ms\n远程文件路径=[{}]\n本地文件保存路径=[{}]",
					fileArray[0],host,port,username,timeout,remotePath,localPath);
			
			SFTPTransfer sftp = new SFTPTransfer();
        
			sftp.downloadFileList(host, port, username, "",timeout,privateKey, "", localPath, remotePath, fileArray, new ArrayList<String>());
			FileUtil.deTarFile(localPath + File.separator + fileArray[0],"GBK",localPath,"UTF-8");
		}catch(BaseException e){
			String errMsg = String.format("机构[%s]与[%s]通道[%s]日对账失败，下载解压[%s]通道的对账文件[%s]失败，原因：[%s]", orgId,pCId,DateUtil.date3Str(chkAD),this.pCId,fileArray[0],e.getErrorDesc());
			throw new BaseException(RespCd.NCPO6037,e,errMsg);
		}catch (Exception e) {
			String errMsg = String.format("机构[%s]与[%s]通道[%s]日对账失败，下载解压[%s]通道的对账文件[%s]失败，原因：[%s]", orgId,pCId,DateUtil.date3Str(chkAD),this.pCId,fileArray[0],e.getMessage());
			throw new BaseException(RespCd.NCPO6037,e,errMsg);
		}
		
	}
	
	/**
	 * 
	 * Description:汇总对账文件-登记入库
	 *
	 * @author jjw
	 * @data 2019年9月7日
	 */
	private int regCsum(File csumFile){
		
		TdChkaSumMapper tdChkaSumMapper = sqlSession.getMapper(TdChkaSumMapper.class);
		List<TdChkaSum> tdChkaSumICs = new ArrayList<TdChkaSum>();
		List<String> chkASumList = null;
		
		try {
			chkASumList = FileUtil.readFile(csumFile.getAbsolutePath());
		} catch (Exception e) {
			String errMsg = String.format("机构[%s]与[%s]通道[%s]日对账失败，对账文件[%s]读取失败", orgId,pCId,DateUtil.date3Str(chkAD),csumFile.getAbsolutePath());
			throw new BaseException(RespCd.NCPO6037,e,errMsg);
		}
		
		//删除冗余数据
		tdChkaSumMapper.delReDun(orgId, chkAD);
		
		int count = 0;
		for(String chkASum : chkASumList){
			String[] items = chkASum.split("\\|");
			tdChkaSumICs.add(fillTdChkaSum(items));
			count++;
			
			//每250条，批量插入一次
			if(count % 250 == 0){
				tdChkaSumMapper.batchInsert(tdChkaSumICs);
				tdChkaSumICs.clear();
			}
		}
		
		if(tdChkaSumICs.size() != 0){
			tdChkaSumMapper.batchInsert(tdChkaSumICs);
		}
		
		return count;
		
	}
	
	/**
	 * 
	 * Description:汇兑业务明细对账文件-登记入库
	 *
	 * @author jjw
	 * @data 2019年9月7日
	 */
	private int regCdtt(File cdttFile){

		//入临时明细对账表
		String tableName = "td_chka_rm_" + orgId;

		ncsChkAComponent.truncateRmDetail(tableName,orgId,pCId,DateUtil.date3Str(chkAD));

		int count = 0;
		if(cdttFile.length() > 0){
			count = ncsChkAComponent.loadRmDetail(tableName,orgId,pCId,DateUtil.date3Str(chkAD),cdttFile);
		}

		return count;
		
	}
	
	/**
	 * 
	 * Description:实时借贷业务明细对账文件-登记入库
	 *
	 * @author jjw
	 * @data 2019年9月7日
	 */
	private int regRtcd(File rtcdFile){

		String tableName = "td_chka_dr_" + orgId;

		ncsChkAComponent.truncateDrDetail(tableName,orgId,pCId,DateUtil.date3Str(chkAD));

		int count = 0;
		if(rtcdFile.length() > 0){
			count = ncsChkAComponent.loadDrDetail(tableName,orgId,pCId,DateUtil.date3Str(chkAD),rtcdFile);
		}

		return count;
		
	}
	
	/**
	 * 
	 * Description:填充TdChkaSum对象的属性
	 *
	 * @author jjw
	 * @data 2019年9月7日
	 */
	private TdChkaSum fillTdChkaSum(String[] items){
		
		TdChkaSum tdChkaSum = new TdChkaSum();
		tdChkaSum.setChkAD(DateUtil.str2Date(items[0], "yyyyMMdd"));
		tdChkaSum.setbNo(items[1]);
		tdChkaSum.setMsgNo(items[2]);
		tdChkaSum.setBizTyp(items[3]);
		tdChkaSum.setContFlg(items[4]);
		tdChkaSum.setCurKnd(items[5]);
		tdChkaSum.setDrTotDN(Integer.parseInt(items[6]));
		tdChkaSum.setDrTotAmt(new BigDecimal(items[7]));
		tdChkaSum.setLoanTotDN(Integer.parseInt(items[8]));
		tdChkaSum.setLoanTotAmt(new BigDecimal(items[9]));
		tdChkaSum.setCrLoanTotDN(Integer.parseInt(items[10]));
		tdChkaSum.setCrLoanTotAmt(new BigDecimal(items[11]));
		tdChkaSum.setRscsCrLoanTotDN(Integer.parseInt(items[12]));
		tdChkaSum.setRscsCrLoanTotAmt(new BigDecimal(items[13]));
		
		return tdChkaSum;
		
	}

}
